package org.ysling.litemall.core.weixin.service;

import com.github.binarywang.wxpay.bean.marketing.transfer.PartnerTransferRequest;
import com.github.binarywang.wxpay.bean.marketing.transfer.PartnerTransferResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.ysling.litemall.core.weixin.request.WxPartnerTransferResult;
import org.ysling.litemall.core.weixin.request.WxPartnerTransferRequest;
import org.ysling.litemall.db.domain.*;
import org.ysling.litemall.db.service.LitemallOrderGoodsService;
import org.ysling.litemall.db.service.LitemallOrderService;
import org.ysling.litemall.db.service.LitemallRewardService;
import org.ysling.litemall.db.service.LitemallUserService;
import org.ysling.litemall.db.constant.RewardConstant;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class WeixinPayCoreService {

    private final Log logger = LogFactory.getLog(WeixinPayCoreService.class);

    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private LitemallOrderService orderService;
    @Autowired
    private LitemallOrderGoodsService orderGoodsService;
    @Autowired
    private LitemallRewardService rewardService;
    @Autowired
    private LitemallUserService userService;

    /**
     * 微信退款
     * @param order
     */
    public WxPayRefundResult wxPayRefund(LitemallOrder order){
        if (order.getPayId() == null){
            throw new RuntimeException("仅线上支付支持微信退款");
        }
        // 微信退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setTransactionId(order.getPayId());
        wxPayRefundRequest.setOutTradeNo(order.getOrderSn());
        wxPayRefundRequest.setOutRefundNo("refund_" + order.getOrderSn());
        // 元转成分
        Integer refundFee = order.getActualPrice().multiply(new BigDecimal(100)).intValue();
        Integer totalFee = order.getOrderPrice().multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setRefundFee(refundFee);

        return getWxPayRefundResult(wxPayRefundRequest);
    }


    /**
     * 微信退款
     * @param order
     */
    public WxPayRefundResult wxPayAftersaleRefund(LitemallOrder order , LitemallAftersale aftersaleOne){
        if (order.getPayId() == null){
            throw new RuntimeException("仅线上支付支持微信退款");
        }
        // 微信退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setTransactionId(order.getPayId());
        wxPayRefundRequest.setOutTradeNo(order.getOrderSn());
        wxPayRefundRequest.setOutRefundNo("refund_" + order.getOrderSn());
        // 元转成分
        Integer totalFee = aftersaleOne.getAmount().multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(order.getActualPrice().multiply(new BigDecimal(100)).intValue());
        wxPayRefundRequest.setRefundFee(totalFee);

        return getWxPayRefundResult(wxPayRefundRequest);
    }


    private WxPayRefundResult getWxPayRefundResult(WxPayRefundRequest wxPayRefundRequest) {
        WxPayRefundResult wxPayRefundResult;
        try {
            wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException("订单退款失败");
        }
        if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            throw new RuntimeException("订单退款失败");
        }
        if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            throw new RuntimeException("订单退款失败");
        }
        return wxPayRefundResult;
    }


    /**
     * 商家付款到零钱
     * @param user
     * @param order
     */
    public PartnerTransferResult merchantsPayToChange(LitemallUser user , LitemallOrder order){
        //判断是否线上支付
        BigDecimal price = order.getActualPrice();
        if (price == null || price.intValue() < 1 || price.intValue() > 1000) {
            logger.info("系统自动打款---订单金额不正确---" + order.getOrderSn());
            return null;
        } else if (!ObjectUtils.allNotNull(order.getPayId() , order.getPayTime())) {
            logger.info("系统自动打款---订单未线上支付---" + order.getOrderSn());
            return null;
        } else if (ObjectUtils.allNotNull(order.getBatchId() , order.getBatchTime())) {
            logger.info("系统自动打款---订单已打款---" + order.getOrderSn());
            return null;
        } else if (!ObjectUtils.allNotNull(user.getTrueName() , user.getWeixinOpenid())) {
            logger.info("系统自动打款---店家信息不正确---" + order.getOrderSn());
            throw new RuntimeException("系统自动打款---店铺信息不正确---" + order.getOrderSn());
        }

        //获取赏金分享信息
        LitemallReward reward = rewardService.findByOrderId(order.getId());

        // 赏金金额 = 奖励金额 * 下单数量 * 100 单位分
        int totalAward = BigDecimal.valueOf(0).intValue();

        // 转账总金额 = 订单金额 - (订单金额 * 0.05) * 100  单位分
        int totalAmount = order.getActualPrice()
                .subtract(order.getActualPrice().multiply(new BigDecimal("0.05")))
                .multiply(new BigDecimal(100))
                .max(new BigDecimal(0))
                .intValue();


        //转账明细列表
        List<PartnerTransferRequest.TransferDetail> transferDetailList = new ArrayList<>();
        //赏金转账明细
        if (reward != null && reward.getStatus().equals(RewardConstant.STATUS_SUCCEED)) {
            LitemallUser creatorUser = userService.findById(reward.getCreatorUserId());
            LitemallOrderGoods orderGoods = orderGoodsService.getByOrderId(order.getId());

            // 赏金金额 = 奖励金额 * 下单数量 * 100 单位分
            totalAward = reward.getAward().multiply(new BigDecimal(orderGoods.getNumber()))
                    .min(order.getActualPrice())
                    .multiply(new BigDecimal(100))
                    .intValue();

            //赏金转账明细
            PartnerTransferRequest.TransferDetail rewardTransferDetail = new PartnerTransferRequest.TransferDetail();
            rewardTransferDetail.setTransferAmount(totalAward);//转账金额
            rewardTransferDetail.setTransferRemark("赏金分享奖励发放");//转账备注
            rewardTransferDetail.setOpenid(creatorUser.getWeixinOpenid());//用户openid
            rewardTransferDetail.setOutDetailNo(order.getOrderSn()+reward.getId());//商家明细单号

            //添加进转账明细列表
            //transferDetailList.add(rewardTransferDetail);
        }

        // 商品转账金额 = 总转账金额 - 赏金奖励金额
        int totalGoods = new BigDecimal(totalAmount).subtract(new BigDecimal(totalAward))
                .max(new BigDecimal(0))
                .intValue();

        //订单转账明细
        PartnerTransferRequest.TransferDetail orderTransferDetail = new PartnerTransferRequest.TransferDetail();
        orderTransferDetail.setTransferAmount(totalGoods);//转账金额
        orderTransferDetail.setOpenid(user.getWeixinOpenid());//用户id
        orderTransferDetail.setTransferRemark("商品销售金额发放");//转账备注
        orderTransferDetail.setOutDetailNo(order.getOrderSn()+order.getId());//商家明细单号

        //添加进转账明细列表
        transferDetailList.add(orderTransferDetail);

        //订单请求参数
        WxPartnerTransferRequest transferRequest = new WxPartnerTransferRequest();
        //将转账明细列表添加进转账参数
        transferRequest.setTransferDetailList(transferDetailList);
        transferRequest.setAppid(wxPayService.getConfig().getAppId());
        transferRequest.setOutBatchNo(order.getOrderSn());//商家批次单号
        transferRequest.setBatchName("商品确认收货转账");//批次名称
        transferRequest.setTotalAmount(totalAmount);//转账总金额
        transferRequest.setTotalNum(transferDetailList.size());//转账总笔数
        transferRequest.setBatchRemark("商品确认收货转账");//批次备注

        //返回请求返回参数
        PartnerTransferResult transferResult;
        try {
            //发送请求
            transferResult = new WxPartnerTransferResult(wxPayService).batchTransfer(transferRequest);
            //请求成功添加打款id
            order.setBatchId(transferResult.getBatchId());
            order.setBatchTime(LocalDateTime.now());
            orderService.updateSelective(order);
            //请求成功添加打款id
            if (reward != null) {
                reward.setBatchId(transferResult.getBatchId());
                reward.setBatchTime(LocalDateTime.now());
                rewardService.updateSelective(reward);
            }
        }catch (WxPayException e){
            logger.error(e.getMessage(), e);
            if (StringUtils.hasText(e.getErrCodeDes())){
                throw new RuntimeException(e.getErrCodeDes());
            }if (StringUtils.hasText(e.getCustomErrorMsg())){
                throw new RuntimeException(e.getCustomErrorMsg());
            }else {
                throw new RuntimeException("订单确认收货失败，请稍后重试");
            }
        }
        return transferResult;
    }
}
